package Demo3;

public class MatrixChain {
    /**int[] p：表示存储各矩阵的行列数，其中 p[i] 表示第 i 个矩阵的行数和第 i+1 个矩阵的列数。
     int n：表示连乘的矩阵个数。
     int[][] m：表示最优值数组，其中 m[i][j] 表示从第 i 个矩阵乘到第 j 个矩阵所需的最少乘法次数。
     int[][] s：表示最优断开位置的数组，其中 s[i][j] 表示从第 i 个矩阵乘到第 j 个矩阵时，在第 s[i][j] 个矩阵处断开，可以获得最少的乘法次数。
     *
     */

    public static void matrixChain(int[] p, int n, int[][] m, int[][] s) {
        for (int i = 1; i <= n; i++) {
            m[i][i] = 0; // 一个矩阵时，不必划分了。
        }

        for (int r = 2; r <= n; r++) {
            for (int i = 1; i <= n - r + 1; i++) {
                int j = i + r - 1; // 链长为r的连乘矩阵，从第i个到第j个，共r个。
                m[i][j] = m[i + 1][j] + p[i - 1] * p[i] * p[j]; // 假设按[i][i]+[i+1][j]为初始划分。
                s[i][j] = i; // 记住划分位置。

                for (int k = i + 1; k < j; k++) { // 还有多种划分，从而找出最优划分。
                    int t = m[i][k] + m[k + 1][j] + p[i - 1] * p[k] * p[j];
                    if (t < m[i][j]) {
                        m[i][j] = t;
                        s[i][j] = k;
                    }
                }
            }
        }
    }

    public static void main(String[] args) {
        int[] p = {5, 10, 3, 12, 5, 50, 6};
        int n = p.length - 1;
        int[][] m = new int[n + 1][n + 1];
        int[][] s = new int[n + 1][n + 1];

        matrixChain(p, n, m, s);

        // 打印最优值数组m
        System.out.println("最优值数组m：");
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                System.out.print(m[i][j] + " ");
            }
            System.out.println();
        }

        // 打印最优断开位置的数组s
        System.out.println("最优断开位置的数组s：");
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                System.out.print(s[i][j] + " ");
            }
            System.out.println();
        }
    }
}

